package com.fingard.dsp.bank.directbank.abc02;

import com.fingard.client.DspClient;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.abc02.util.RsaHelper;
import com.fingard.dsp.bank.directbank.bankInterface.IWithhold;
import com.fingard.dsp.bank.helpers.FileType;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.TcpReceiver;
import com.fingard.text.StringHelper;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import com.xwbank.sdk.base64.BASE64Encoder;

import java.io.File;
import java.security.PublicKey;

import static com.fingard.text.StringHelper.trimEndFileSp;

public class ABC02Withhold extends ABC02Base implements IWithhold {

    @Override
    public RetAtsBatPayRec d_9208_singlePay(ReqBatPayRec p_req9188) throws Exception {
        return d_PayRec_9208(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9244_QrySinglePay(ReqQryBatPayRec p_req9244) throws Exception {
        return null;
    }

    public RetAtsBatPayRec d_PayRec_9208(ReqBatPayRec p_reqBat) throws Exception {
        //用代付的ATS接收报文类，做代扣的接收报文类，payact做收款方，recact做被扣款方（付款方，多个）
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        try {
            ABC02Header bankHeader = new ABC02Header();
            //构造差额代扣文件
            StringBuilder tmpSbData = new StringBuilder();
            int index = 0;
            String splitStr = "|";
            while (p_reqBat.readRecord()) {
                tmpSbData.append(p_reqBat.readedDetail.askNumber).append(splitStr);
                tmpSbData.append(p_reqBat.readedDetail.recName).append(splitStr);
                tmpSbData.append(p_reqBat.readedDetail.recAct).append(splitStr);
                tmpSbData.append(this.convertCurToBank(p_reqBat.readedDetail.recCur)).append(splitStr);
                tmpSbData.append(p_reqBat.readedDetail.payAmount).append(splitStr);
                tmpSbData.append(p_reqBat.readedDetail.abstractATS).append(splitStr).append("\r\n");
            }
            //构造请求报文
            bankHeader.CCTransCode = "CFRB19";
            bankHeader.ReqSeqNo = p_reqBat.reqBatchNO;
            bankHeader.ReqDateTime = p_reqBat.getPayDateTime();
            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, bankHeader);
            xmlWriter.writeStartElement("Cmp");
            xmlWriter.writeElementString("DbAccNo", getAbcAccNo(p_reqBat.ownAct)); //getAbcAccNo(p_reqBat.ownAct)
            boolean isPrivateArea = getBankConfig().getValueAsBool("isPrivateArea");//是否启用广东省农行区域配置
            if (isPrivateArea) {
                //启用
                String ownArea = p_reqBat.ownAct.substring(0, 2);
                xmlWriter.writeElementString("DbProv", ownArea);
            } else {
                //不启用
                xmlWriter.writeElementString("DbProv", p_reqBat.ownArea);
            }
            xmlWriter.writeElementString("DbCur", this.convertCurToBank(p_reqBat.ownCur));
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("Corp");
            xmlWriter.writeElementString("DbAccName", p_reqBat.ownActName);
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("Cme");
            xmlWriter.writeElementString("InterBusFlag", "9");
            xmlWriter.writeEndElement();
            xmlWriter.writeElementString("Amt", p_reqBat.totalAmt);
            xmlWriter.writeStartElement("Cmp");
            xmlWriter.writeElementString("SumNum", p_reqBat.totalNum);
            xmlWriter.writeEndElement();
            xmlWriter.writeElementString("FileFlag", "1");
            xmlWriter.writeStartElement("Cmp");
            xmlWriter.writeElementString("BatchFileName", p_reqBat.reqBatchNO + ".txt");
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("Corp");
            xmlWriter.writeElementString("SplitStr", "|");
            xmlWriter.writeElementString("Postscript", p_reqBat.useType);
            String NVoucherType = getBankConfig().getMapValueByKey("nVoucherType" + bankHeader.CCTransCode, p_reqBat.ownAct);
            String NFAccNo = getBankConfig().getMapValueByKey("nFAccNo" + bankHeader.CCTransCode, p_reqBat.ownAct);
//            xmlWriter.writeElementString("NVoucherType", "99000000");
            xmlWriter.writeElementString("NVoucherType", NVoucherType);
            xmlWriter.writeElementString("NFAccNo", NFAccNo);
            xmlWriter.writeEndElement();

            //1.ERP先将批量文件上传到ICT的detail目录，然后发起请求报文
            tmpSbData.delete(tmpSbData.length() - 2, tmpSbData.length());
            String tmpLocalMarkPath = getTempFileDirectory() + File.separator + p_reqBat.reqBatchNO + ".txt";
            WriteBankLogLn2("批次明细序号映射文件路径: " + tmpLocalMarkPath);
            FileHelper.writeFile(tmpLocalMarkPath, tmpSbData);
            String tmpFilePath = "";
            String tmpDataFileName = p_reqBat.reqBatchNO + ".txt";
            if (StringHelper.isNullOrEmpty(bankFront.bkRecFolder)) {
                bankFront.bkRecFolder = bankFront.bkPayFolder;
            }
            tmpFilePath = StringHelper.trimEnd(bankFront.bkRecFolder, File.separator) + File.separator + tmpDataFileName;

//			WriteBankLogLn("发薪文件的保存地址：" + tmpFilePath+"plain");
            String cipherData = "";


            if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                DspClient dspClient = new DspClient(bankFront.dspFileServer);
                dspClient.charsetName = getCharset();
                TcpReceiver retReceiver = dspClient.putFile(isNeedHiddleField ? cipherData : tmpSbData.toString(), FileType.bankFile, tmpFilePath, false);
                if (retReceiver.isCompleted) {
                    String retXml = new String(retReceiver.recBytes, retReceiver.contentStartIndex, retReceiver.contentLength, retReceiver.charsetName);
                    XmlTextReader retXmlRd = new XmlTextReader(retXml);
                    if ("0".equals(retXmlRd.getSimpleText("RespCode"))) {
                        WriteBankLogLn("文件保存至前置机" + tmpFilePath + "成功");
                    } else {
                        WriteBankLogLn("文件保存至前置机" + tmpFilePath + "失败，响应报文：" + retXml);
                    }
                } else {
                    WriteBankLogLn("文件" + tmpFilePath + "保存失败：" + retReceiver.getConnMsg());
                    if (retReceiver.connState.equals(ConnState.FAIL)) {
                        WriteBankLogLn("连接主DSP服务" + bankFront.dspFileServer + "失败");
                    }
                }
            } else if ("smb".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                WriteBankLogLn("请求代收付文件内容为:" + tmpSbData.toString());
                //上传文件到前置机目录
                if (FileHelper.existFile(tmpLocalMarkPath)) {
                    String remotePath = StringHelper.trimEnd(bankFront.bkRecFolder, File.separator) + "/";
                    WriteBankLogLn("文件上传共享目录地址为:" + remotePath);
                    int result = SmbFileUtil.smbUploadingInChar(tmpLocalMarkPath, "", remotePath);
                    if (result == -1) {
                        retAts.respCode = "-1";
                        retAts.respInfo = "上传文件到前置机目录异常";
                        retAts.writeRetToATS();
                        return retAts;
                    } else if (result == 1) {
                        retAts.respCode = "-1";
                        retAts.respInfo = "文件已存在共享目录无需重复上传";
                        retAts.writeRetToATS();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "本地批付文件不存在";
                    retAts.writeRetToATS();
                    return retAts;
                }
            } else {
                WriteBankLogLn("请求代收付文件内容为:" + tmpSbData.toString());
                WriteBankLogLn("文件上传地址为:" + tmpFilePath);
                if (isNeedHiddleField) {

                    String bankPubKeyPath = getBankConfig().getValueAsString("BankPubKeyPath");
                    PublicKey publicKey = RsaHelper.decodePublicKeyFromFile(bankPubKeyPath);
                    //对文件内容进行加密
                    byte[] encryptedDate = RsaHelper.encryptData(tmpSbData.toString().getBytes("gbk"), publicKey);
                    cipherData = new BASE64Encoder().encode(encryptedDate);
                    FileHelper.writeFile(tmpFilePath, cipherData, getCharset());
                } else {
                    FileHelper.writeFile(tmpFilePath, tmpSbData.toString(), getCharset());
                }
            }
            xmlWriter.writeEndDocument();// 写入报文完成
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());// 发送银行
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                // 解析银行返回
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRespCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    String tmpRespSource = tmpBkReader.getFirstText("/ap/RespSource");
                    retAts.respCode = "0";
                    retAts.reqSeqID = p_reqBat.reqBatchNO;
                    retAts.transState = tmpRespSource + "+" + tmpRespCode;
                    retAts.payInfoCode = retAts.transState;
                    retAts.respInfo = StringHelper.joinNotEmpty("+", tmpRetInfo, tmpRetRxtInfo);
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = tmpStrRet[0];
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }

        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            WriteBankLogLn(e);
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_reqBat.reqBatchNO;
        }
        retAts.writeRetToATS();
        return retAts;
    }
}
